// Package options contains flags and options for initializing an APIServer.
package options

import (
	genericoptions "gitee.com/han-jiahao666/iam/internal/pkg/options"
	"gitee.com/han-jiahao666/iam/internal/pkg/server"
	"github.com/marmotedu/component-base/pkg/util/idutil"
)

// Options 结构体用于运行 iam api 服务器，包含了各种配置选项。
type Options struct {
	// GenericServerRunOptions 是通用的服务器运行选项
	GenericServerRunOptions *genericoptions.ServerRunOptions `json:"server"   mapstructure:"server"`
	// GRPCOptions 是 gRPC 相关的选项
	GRPCOptions *genericoptions.GRPCOptions `json:"grpc"     mapstructure:"grpc"`
	// InsecureServing 是不安全的服务相关选项
	InsecureServing *genericoptions.InsecureServingOptions `json:"insecure" mapstructure:"insecure"`
	// SecureServing 是安全的服务相关选项
	SecureServing *genericoptions.SecureServingOptions `json:"secure"   mapstructure:"secure"`
	// MySQLOptions 是 MySQL 相关的选项
	MySQLOptions *genericoptions.MySQLOptions `json:"mysql"    mapstructure:"mysql"`
	// RedisOptions 是 Redis 相关的选项
	RedisOptions *genericoptions.RedisOptions `json:"redis"    mapstructure:"redis"`
	// JwtOptions 是 JWT 相关的选项
	JwtOptions *genericoptions.JwtOptions `json:"jwt"      mapstructure:"jwt"`
	// Log 是日志相关的选项
	Log *log.Options `json:"log"      mapstructure:"log"`
	// FeatureOptions 是特性相关的选项
	FeatureOptions *genericoptions.FeatureOptions `json:"feature"  mapstructure:"feature"`
}

// NewOptions 函数用于创建一个带有默认参数的 Options 对象。
func NewOptions() *Options {
	// 初始化 Options 结构体的各个字段，使用相应的 New 函数来创建默认配置
	o := Options{
		GenericServerRunOptions: genericoptions.NewServerRunOptions(),
		GRPCOptions:             genericoptions.NewGRPCOptions(),
		InsecureServing:         genericoptions.NewInsecureServingOptions(),
		SecureServing:           genericoptions.NewSecureServingOptions(),
		MySQLOptions:            genericoptions.NewMySQLOptions(),
		RedisOptions:            genericoptions.NewRedisOptions(),
		JwtOptions:              genericoptions.NewJwtOptions(),
		Log:                     log.NewOptions(),
		FeatureOptions:          genericoptions.NewFeatureOptions(),
	}

	return &o
}

// ApplyTo 方法将运行选项应用到方法接收者，并返回自身。
// 目前该方法未实现具体逻辑，直接返回 nil。
func (o *Options) ApplyTo(c *server.Config) error {
	return nil
}

// Flags 方法根据不同的配置部分名称返回特定 APIServer 的标志集。
func (o *Options) Flags() (fss cliflag.NamedFlagSets) {
	// 为不同的配置部分添加相应的标志
	o.GenericServerRunOptions.AddFlags(fss.FlagSet("generic"))
	o.JwtOptions.AddFlags(fss.FlagSet("jwt"))
	o.GRPCOptions.AddFlags(fss.FlagSet("grpc"))
	o.MySQLOptions.AddFlags(fss.FlagSet("mysql"))
	o.RedisOptions.AddFlags(fss.FlagSet("redis"))
	o.FeatureOptions.AddFlags(fss.FlagSet("features"))
	o.InsecureServing.AddFlags(fss.FlagSet("insecure serving"))
	o.SecureServing.AddFlags(fss.FlagSet("secure serving"))
	o.Log.AddFlags(fss.FlagSet("logs"))

	return fss
}

// String 方法将 Options 结构体转换为 JSON 字符串表示形式。
func (o *Options) String() string {
	// 将 Options 结构体进行 JSON 编码
	data, _ := json.Marshal(o)

	return string(data)
}

// Complete 方法设置默认的 Options。
// 如果 JwtOptions 的 Key 为空，则生成一个新的密钥。
// 最后调用 SecureServing 的 Complete 方法。
func (o *Options) Complete() error {
	if o.JwtOptions.Key == "" {
		o.JwtOptions.Key = idutil.NewSecretKey()
	}

	return o.SecureServing.Complete()
}
